import { GenericEnvStore } from "@/modules/dev-env/store/generic-env-store.ts";
import type { LocalVersionItem, ToolInstallVersionItem } from "@/modules/dev-env/common/types.ts";
import type { BaseEnvMirror } from "@/modules/dev-env/mirror/mirror.ts";
import { PythonNpmMirror, PythonOfficialMirror } from "@/modules/dev-env/python/python-mirror.ts";
import path from "@/framework/util/path.ts";
import type { EnvTableAction, EnvVariableConfig } from "@/modules/dev-env/store/types.ts";
import { execInTerminal } from "@/util/system-utils2.ts";
import type { UnzipCompleteArgs } from "@common/archives-file-types.ts";
import { noop } from "@/framework/util/warning.ts";
import { EnvTree } from "@/modules/dev-env/common/tree.ts";

export class PythonEnvStore extends GenericEnvStore<PythonEnvStore> {
  constructor() {
    super("python");
    this.icon = "icon-python";

    this.tableActions = this._tableActions();
  }

  private _tableActions(): EnvTableAction[] {
    return [
      {
        key: "python-console",
        name: "Python控制台",
        icon: "icon-python",
        onClick: it => execInTerminal(`python`, { cwd: it.installPath }),
      },
    ];
  }

  protected getMirrors0(): BaseEnvMirror[] {
    return [new PythonNpmMirror(), new PythonOfficialMirror()];
  }

  protected async getVersionInfo(versionDir: string): Promise<LocalVersionItem | undefined> {
    const currentDirname = path.basename(versionDir);
    if (!/^python[a-zA-Z]+-/.test(currentDirname)) {
      return undefined;
    }

    const pythonExe = path.join(versionDir, "python.exe");
    let isPythonDir = await native.fs.exists(pythonExe);
    const installConfig = await this._getInstallJson(versionDir);
    if (installConfig != null && /python.*\.exe$/.test(installConfig["executable"])) {
      isPythonDir = true;
    }

    if (isPythonDir) {
      // pythoncore-3.14.0-b4-x64
      const [, version] = currentDirname.split("-");
      return {
        displayName: installConfig?.["display-name"],
        version: version,
        installPath: versionDir,
      };
    }

    return undefined;
  }

  private async _getInstallJson(versionDir: string): Promise<Record<string, any> | undefined> {
    const filePath = path.join(versionDir, "__install__.json");
    const exists = await native.fs.exists1(filePath);
    if (!exists) {
      return undefined;
    }

    try {
      return await native.fs.readFileJson(filePath);
    } catch (e) {
      console.error("PythonEnvStore._getInstallJson() error", e);
    }
  }

  getEnvVariables0(): EnvVariableConfig[] {
    return [
      {
        name: "Path0",
        getValue: () => path.join(this.installDir, EnvTree.currentVersionDir),
        settable: false,
        readonly: true,
        copyName: false,
      },
      {
        name: "Path1",
        getValue: () => path.join(this.installDir, EnvTree.currentVersionDir, "Scripts"),
        settable: false,
        readonly: true,
        copyName: false,
      },
    ];
  }

  async afterUnzipComplete(e: UnzipCompleteArgs, version: ToolInstallVersionItem) {
    const isNupkg = version.url.endsWith(".nupkg");
    if (isNupkg) {
      // 比较老的版本从NuGet源下载,使用nupkg包解压安装
      // 将解压的临时文件移动到安装目录, .nuokg包解压后python相关文件在tools目录下
      const versionDir = path.join(this.installDir, EnvTree.versionsDir, version.installPath);
      const tempToolsDir = path.join(e.fileDir, "tools");
      // 复制文件夹
      await native.fs.cp(tempToolsDir, versionDir, {
        recursive: true,
        force: true,
        errorOnExist: false,
        preserveTimestamps: true,
      });
      // 删除临时文件夹
      native.fs.rm(e.fileDir, { recursive: true, force: true, maxRetries: 3 }).catch(noop);
    }
  }
}
